//
// Created by Administrator on 2025/4/20.
//

#include "ConnectionPool.h"


ConnectionPool * ConnectionPool::getInstance(){
    static ConnectionPool connPool;
    return &connPool;
}

std::shared_ptr<Connection> ConnectionPool::getConnection(){
    std::unique_lock<std::mutex> lock(m_mutex);
    while (m_conn_queue.empty()){
        if(std::cv_status::timeout == m_cond.wait_for(lock, std::chrono::milliseconds(m_conn_timeout))){
            if(m_conn_queue.empty()){
                return nullptr;
            }
        }
    }
    // share_ptr析构时 不要关掉连接，将连接加入回队列中
    std::shared_ptr<Connection> sp(m_conn_queue.front(), [&](Connection * conPtr){
        std::unique_lock<std::mutex> lock(m_mutex);
        m_conn_queue.push(conPtr);
    });
    m_conn_queue.pop();
    m_cond.notify_all();
    return sp;
}

ConnectionPool::ConnectionPool(){
    if(!loadConf()){
        return;
    }
    for(int i = 0; i < m_init_size; i++){
        Connection * connPtr = new Connection;
        connPtr->connect(m_host, m_username, m_password, m_db, m_port);
        m_conn_queue.push(connPtr);
        m_active_num++;
    }
    std::thread produce(std::bind(&ConnectionPool::produceConnTask, this));
    produce.detach();
}
ConnectionPool::~ConnectionPool(){

}
bool ConnectionPool::loadConf(){
    if(m_conf_filename){
        return true;
    }

    return false;
}

void ConnectionPool::produceConnTask(){
    for(;;){
        std::unique_lock<std::mutex> lock(m_mutex);
        while(!m_conn_queue.empty()){
            m_cond.wait(lock);
        }
        if(m_active_num < m_max_size){
            Connection * connPtr = new Connection;
            connPtr->connect(m_host, m_username, m_password, m_db, m_port);
            m_conn_queue.push(connPtr);
            m_active_num++;
        }
        m_cond.notify_all();
    }
}